/**
 * @file:          FlashManager.h
 * @brief:
 * @details:
 * @author:        wjh
 * @date created:  2023.08.22
 * @version:       1.0.0
 * @par copyright (c):
 *
 * @par history (desc):
 *   version:1.0.0, wjh, 2023.08.22,16:05:16
 */

#ifndef _FLASHMANAGER_H_
#define _FLASHMANAGER_H_

/* Include Files **************************************************************/
#include "Datatype.h"
#include "DriverList.h"

/* Macro Definition ***********************************************************/
#define DATA_TABLE_NUM_SIZE 225
#define DATA_TYPE_STR_SIZE 10
#define DATA_NAME_SIR_SIZE 10
#define FLASH_MANAGER_WRITE_DELAY_MS 20

#define FLOAT_DISP_MASK 1000

/* Data Type Define ***********************************************************/
enum DataSolutionMethod
{
    DataSolutionMethod_Save = 0,
    DataSolutionMethod_Load = 1,
    DataSolutionMethod_List = 2,
    DataSolutionMethod_Write = 3,
    DataSolutionMethod_Read = 4,
    DataSolutionMethod_Check = 5,
};

enum FlashParam_RebootToTakeEffect
{
    FlashParam_RebootToTakeEffect_No = 0,
    FlashParam_RebootToTakeEffect_Yes = 1,
};

enum FlashParamId
{
    /*** version param */
    FlashParamId_param_flash_param_version = 0,

    /*** general param */
    FlashParamId_param_boot_key,
    FlashParamId_param_flash_key_write_retries_num,
    FlashParamId_param_system_startup_delay_ms,
    FlashParamId_param_pwm_period_s,
    FlashParamId_param_task_period_s,
    FlashParamId_param_use_default_param,
    FlashParamId_param_singleturn_control_mode,
    FlashParamId_param_elec_angle_calibration_standar_deg,
    FlashParamId_param_elec_offset,
    FlashParamId_param_phase_order_invert,
    FlashParamId_param_emergency_pin_mode,
    FlashParamId_param_stall_mode,
    FlashParamId_param_stall_cur_A,
    FlashParamId_param_stall_pos_err_rad,
    FlashParamId_param_calibration_dir,
    FlashParamId_param_encoder_cal_count_max,
    FlashParamId_param_encoder_read_count,
    FlashParamId_param_delay_ms_per_step,
    FlashParamId_param_delay_ms_per_read,
    FlashParamId_param_ud_cal_set,
    FlashParamId_param_motion_dir,
    FlashParamId_param_encoder_calibtate_official_cal_count_max,
    FlashParamId_param_encoder_calibtate_official_ud_cal_set,
    FlashParamId_param_encoder_calibration_round_count,
    FlashParamId_elec_offset_err_deg,

    /*** driver board param */
    FlashParamId_driver_board_param_power_supply_V,
    FlashParamId_driver_board_param_adc_ref_V,
    FlashParamId_driver_board_param_amp_gain,
    FlashParamId_driver_board_param_power_voltage_sample_gain,
    FlashParamId_driver_board_param_R_of_current_sample_ohm,
    FlashParamId_driver_board_param_adc_calibration_start_index,
    FlashParamId_driver_board_param_adc_calibration_buffer_size,
    FlashParamId_driver_board_param_led_toggle_period_s,
    FlashParamId_driver_board_param_current_dir,
    FlashParamId_driver_board_param_pwm_output_en,
    FlashParamId_driver_board_param_mos_Ron,
    FlashParamId_driver_board_param_mos_deadtime,
    FlashParamId_driver_board_param_mos_rise_fall_time,
    FlashParamId_driver_board_param_mos_max_peak_current,
    FlashParamId_driver_board_param_mos_max_continuous_current,

    /*** motor param */
    FlashParamId_motor_param_R,
    FlashParamId_motor_param_L,
    FlashParamId_motor_param_Ke,
    FlashParamId_motor_param_Kt,
    FlashParamId_motor_param_mass,
    FlashParamId_motor_param_J,
    FlashParamId_motor_param_B,
    FlashParamId_motor_param_stepping_angle_degree,
    FlashParamId_motor_param_phase_nums,
    FlashParamId_motor_param_pole_pair,
    FlashParamId_motor_param_power_supply,
    FlashParamId_motor_param_rated_voltage,
    FlashParamId_motor_param_rated_current,
    FlashParamId_motor_param_maximum_holding_torque,

    /*** encoder param */
    FlashParamId_encoder_param_direction,
    FlashParamId_encoder_parma_encoder_bit,
    FlashParamId_encoder_param_encoder_max_pulse,
    FlashParamId_encoder_param_fake_encoder_en,
    FlashParamId_encoder_param_fake_encoder_step,

    /*** mcu param */
    FlashParamId_mcu_param_sysclk_hz,
    FlashParamId_mcu_param_HSE_hz,
    FlashParamId_mcu_param_uart_baudrate,
    FlashParamId_mcu_param_input_pulse_counter_trigger_mode,
    FlashParamId_mcu_param_input_pulse_counter_filter_level,

    /*** controller param */
    FlashParamId_controller_param_control_algorithm,
    FlashParamId_controller_param_en_feedforward_idiq,
    FlashParamId_controller_param_en_feedforward_uduq,

    FlashParamId_controller_pos_loop_pid_param_en,
    FlashParamId_controller_pos_loop_pid_param_bypass,
    FlashParamId_controller_pos_loop_pid_param_kp,
    FlashParamId_controller_pos_loop_pid_param_ki,
    FlashParamId_controller_pos_loop_pid_param_kd,
    FlashParamId_controller_pos_loop_pid_param_kc,
    FlashParamId_controller_pos_loop_pid_ud_filter_param_en,
    FlashParamId_controller_pos_loop_pid_ud_filter_param_fc,
    FlashParamId_controller_pos_loop_pid_param_limit_ui,
    FlashParamId_controller_pos_loop_pid_parma_limit_out,
    FlashParamId_controller_pos_loop_pid_fal_param_en,
    FlashParamId_controller_pos_loop_pid_fal_param_a,
    FlashParamId_controller_pos_loop_pid_fal_param_d,
    FlashParamId_controller_pos_loop_pid_fal_param_zoom,
    FlashParamId_controller_pos_loop_pid_fal_param_section_nums,
    FlashParamId_controller_pos_loop_pid_fal_param_inteval_gain,

    FlashParamId_controller_spd_loop_pid_param_en,
    FlashParamId_controller_spd_loop_pid_param_bypass,
    FlashParamId_controller_spd_loop_pid_param_kp,
    FlashParamId_controller_spd_loop_pid_param_ki,
    FlashParamId_controller_spd_loop_pid_param_kd,
    FlashParamId_controller_spd_loop_pid_param_kc,
    FlashParamId_controller_spd_loop_pid_ud_filter_param_en,
    FlashParamId_controller_spd_loop_pid_ud_filter_param_fc,
    FlashParamId_controller_spd_loop_pid_param_limit_ui,
    FlashParamId_controller_spd_loop_pid_parma_limit_out,
    FlashParamId_controller_spd_loop_pid_fal_param_en,
    FlashParamId_controller_spd_loop_pid_fal_param_a,
    FlashParamId_controller_spd_loop_pid_fal_param_d,
    FlashParamId_controller_spd_loop_pid_fal_param_zoom,
    FlashParamId_controller_spd_loop_pid_fal_param_section_nums,
    FlashParamId_controller_spd_loop_pid_fal_param_inteval_gain,

    FlashParamId_controller_cur_loop_pid_param_en,
    FlashParamId_controller_cur_loop_pid_param_bypass,
    FlashParamId_controller_cur_loop_pid_param_kp,
    FlashParamId_controller_cur_loop_pid_param_ki,
    FlashParamId_controller_cur_loop_pid_param_kd,
    FlashParamId_controller_cur_loop_pid_param_kc,
    FlashParamId_controller_cur_loop_pid_ud_filter_param_en,
    FlashParamId_controller_cur_loop_pid_ud_filter_param_fc,
    FlashParamId_controller_cur_loop_pid_param_limit_ui,
    FlashParamId_controller_cur_loop_pid_parma_limit_out,
    FlashParamId_controller_cur_loop_pid_fal_param_en,
    FlashParamId_controller_cur_loop_pid_fal_param_a,
    FlashParamId_controller_cur_loop_pid_fal_param_d,
    FlashParamId_controller_cur_loop_pid_fal_param_zoom,
    FlashParamId_controller_cur_loop_pid_fal_param_section_nums,
    FlashParamId_controller_cur_loop_pid_fal_param_inteval_gain,

    FlashParamId_controller_leso_param_b0k,
    FlashParamId_controller_leso_param_b0,
    FlashParamId_controller_leso_param_z3k,
    FlashParamId_controller_leso_param_wp,
    FlashParamId_controller_leso_param_ws,
    FlashParamId_controller_leso_param_wd,

    FlashParamId_controller_fwc_param_en,
    FlashParamId_controller_fwc_param_I_max,
    FlashParamId_controller_fwc_param_L,
    FlashParamId_controller_fwc_param_phi_e,
    FlashParamId_controller_fwc_param_pole_pair,
    FlashParamId_controller_fwc_param_wm_base,

    FlashParamId_controller_cur_filter_param_en,
    FlashParamId_controller_cur_filter_param_Ts,
    FlashParamId_controller_cur_filter_param_fc,

    FlashParamId_controller_z3_filter_binary_second_order_param_en,
    FlashParamId_controller_z3_filter_binary_second_order_param_fc,
    FlashParamId_controller_z3_filter_binary_second_order_param_depth,
    FlashParamId_controller_z3_filter_binary_second_order_param_zeta_0N,
    FlashParamId_controller_z3_filter_binary_second_order_param_zeta_0D,

    FlashParamId_controller_spd_out_filter_binary_second_order_param_en,
    FlashParamId_controller_spd_out_filter_binary_second_order_param_fc,
    FlashParamId_controller_spd_out_filter_binary_second_order_param_depth,
    FlashParamId_controller_spd_out_filter_binary_second_order_param_zeta_0N,
    FlashParamId_controller_spd_out_filter_binary_second_order_param_zeta_0D,

    FlashParamId_controller_td_param_en,
    FlashParamId_controller_td_param_h0_gain_h,
    FlashParamId_controller_td_fhan_param_f0,
    FlashParamId_controller_td_param_d_gain,
    FlashParamId_controller_td_param_dd_gain,

    FlashParamId_controller_spd_out_filter_notch_0_param_en,
    FlashParamId_controller_spd_out_filter_notch_0_param_f0,
    FlashParamId_controller_spd_out_filter_notch_0_param_f_width,
    FlashParamId_controller_spd_out_filter_notch_0_param_depth,
    FlashParamId_controller_spd_out_filter_notch_1_param_en,
    FlashParamId_controller_spd_out_filter_notch_1_param_f0,
    FlashParamId_controller_spd_out_filter_notch_1_param_f_width,
    FlashParamId_controller_spd_out_filter_notch_1_param_depth,
    FlashParamId_controller_spd_out_filter_notch_2_param_en,
    FlashParamId_controller_spd_out_filter_notch_2_param_f0,
    FlashParamId_controller_spd_out_filter_notch_2_param_f_width,
    FlashParamId_controller_spd_out_filter_notch_2_param_depth,

    FlashParamId_controller_motor_ripple_compensator_en,
    FlashParamId_controller_motor_ripple_compensator_sin_coeffs_0_term_A,
    FlashParamId_controller_motor_ripple_compensator_sin_coeffs_0_term_n,
    FlashParamId_controller_motor_ripple_compensator_sin_coeffs_0_term_phi,
    FlashParamId_controller_motor_ripple_compensator_sin_coeffs_1_term_A,
    FlashParamId_controller_motor_ripple_compensator_sin_coeffs_1_term_n,
    FlashParamId_controller_motor_ripple_compensator_sin_coeffs_1_term_phi,
    FlashParamId_controller_motor_ripple_compensator_sin_coeffs_2_term_A,
    FlashParamId_controller_motor_ripple_compensator_sin_coeffs_2_term_n,
    FlashParamId_controller_motor_ripple_compensator_sin_coeffs_2_term_phi,

    /*** flash manager param */
    FlashParamId_flash_manager_param_checksum_restore_en,

    /*** logger param */
    FlashParamId_logger_param_en,
    FlashParamId_logger_param_continuous_send,
    FlashParamId_logger_param_sample_interval_n,
    FlashParamId_logger_param_n_pack_to_send,

    /*** protection param */
    FlashParamId_protection_param_protect_en,
    FlashParamId_protection_param_protect_report,
    FlashParamId_protection_param_err_code_mask,
    FlashParamId_protection_param_warning_code_mask,
    FlashParamId_protection_param_encoder_mutation_coefficient_upper,
    FlashParamId_protection_param_encoder_mutation_coefficient_lower,
    FlashParamId_protection_param_prt_peak_cur_A,
    FlashParamId_protection_param_prt_continuous_cur_A,
    FlashParamId_protection_param_prt_continuous_time_s,
    FlashParamId_protection_param_prt_over_speed_rad_s,
    FlashParamId_protection_param_prt_over_speed_time_s,
    FlashParamId_protection_param_pos_over_limit_max_rad,
    FlashParamId_protection_param_pos_over_limit_min_rad,
    FlashParamId_protection_param_prt_cmd_mutation_turn,
    FlashParamId_protection_param_prt_track_max_err,
    FlashParamId_protection_param_prt_track_err_time,
    FlashParamId_protection_param_power_voltage_min,
    FlashParamId_protection_param_mcu_temp_max,
    FlashParamId_protection_err_code_backup,
    FlashParamId_protection_warning_code_backup,

    /*** chopper param */
    FlashParamId_chopper_param_chopper_mode,
    FlashParamId_chopper_param_svpwm_mode,
    FlashParamId_chopper_param_base_pwm,
    FlashParamId_chopper_param_offset_pwm_en,
    FlashParamId_chopper_param_offset_pwm,
    FlashParamId_chopper_param_hybrid_decay_ratio,

    /*** step controller param */
    FlashParamId_step_controller_param_pulse_count_max,
    FlashParamId_step_controller_param_subdivision,
    FlashParamId_step_controller_param_pulse_trim_en,
    FlashParamId_step_controller_param_trim_action_period,
    FlashParamId_step_controller_param_extra_trim_pulse,

    /*** communication interface param */
    FlashParamId_cmd_int_param_char_cmd_support,

    /*** system id RL param */
    FlashParamId_system_id_RL_param_param_uin_startup,
    FlashParamId_system_id_RL_param_param_uin_calibrate,
    FlashParamId_system_id_RL_param_param_current_stable_err_condition,
    FlashParamId_system_id_RL_param_param_current_buff_size,
    FlashParamId_system_id_RL_param_param_current_err_size,
    FlashParamId_system_id_RL_param_param_prepare_time,
    FlashParamId_system_id_RL_param_param_normal_R_range_min,
    FlashParamId_system_id_RL_param_param_normal_R_range_max,
    FlashParamId_system_id_RL_param_param_normal_L_range_min,
    FlashParamId_system_id_RL_param_normal_L_range_max,

    /*** motor phase check param*/
    FlashParamId_motor_phase_check_param_run_on_startup,
    FlashParamId_motor_phase_check_param_motor_resistance_tolerance_standar_percent,

    /*** zazen mode param */
    FlashParamId_zazen_param_zazen_en,
    FlashParamId_zazen_param_zazen_trigger_time_s,
    FlashParamId_zazen_param_zazen_gain_pos_kp,
    FlashParamId_zazen_param_zazen_gain_spd_kp,
    FlashParamId_zazen_param_zazen_gain_spd_ki,
    FlashParamId_zazen_param_zazen_gain_cur_kp,
    FlashParamId_zazen_param_zazen_gain_cur_ki,

    /*** flash key */
    FlashParamId_param_flash_key,

    /*** check sum */
    FlashParamId_param_flash_checksum,
};

typedef struct
{
    void *addr;
    uint8_t bytes;
    char *type;
    char *name;
    uint8_t reboot_to_take_effect;
} DataUnit;

typedef union
{
    uint16_t u16[2];
    uint32_t u32;
    int16_t s16[2];
    int32_t s32;
    float f32;
} DataConversion;

typedef struct FlashManager
{
    /* public data */
    Mcu *mcu;

    struct
    {
        union
        {
            uint16_t all;
            struct
            {
                uint8_t minor;
                uint8_t major;
            } byte;
        } number;
        char *release_date;
    } param_version;
    uint16 param_flash_param_valid_key;
    void *param_flash_start_addr;
    uint32_t param_flash_size_byte;
    uint16_t param_checksum_restore_en;

    DataUnit data_table[DATA_TABLE_NUM_SIZE];

    uint16_t data_nums;
    uint16_t data_max_num;
    uint16_t data_total_bytes;
    void *flash_end_addr;
    uint8_t data_is_valid;
    uint16 flash_param_valid_key;
    uint16 async_read_trigger;
    uint16 async_read_index;
    uint16 async_read_bytes_sum;
    uint16 async_list_trigger;
    uint16 async_list_index;
    uint16 async_list_bytes_sum;
    uint16_t flash_checksum;
    uint16_t checksum;
    uint8_t out_reboot_to_take_effect;

    /* private data */

    /* public method */
    void (*ConfigParam)(struct FlashManager *self);
    void (*Init)(struct FlashManager *self);
    void (*RegisterVariableToTable)(struct FlashManager *self, uint16_t data_num, uint8_t reboot_to_take_effect, void *data_addr, uint8_t data_len, char *data_type, char *name);
    uint8_t (*SaveVariableIntoFlash)(struct FlashManager *self, char *name);
    uint8_t (*LoadVariableFromFlash)(struct FlashManager *self, char *name);
    uint8_t (*SaveAllVariableIntoFlash)(struct FlashManager *self);
    uint8_t (*LoadAllVariableFromFlash)(struct FlashManager *self);
    uint8_t (*ListVariableOfSystem)(struct FlashManager *self, char *name);
    uint8_t (*ListAllVariableOfSystem)(struct FlashManager *self);
    uint8_t (*WriteVariableIntoFlash)(struct FlashManager *self, char *name, char *data_str);
    uint8_t (*ReadVariableFromFlash)(struct FlashManager *self, char *name);
    uint8_t (*ReadAllVariableFromFlash)(struct FlashManager *self);
    void (*ReadAllVariableFromFlashAsync_Trigger)(struct FlashManager *self);
    void (*ReadAllVariableFromFlashAsync_Task)(struct FlashManager *self);
    void (*ListAllVariableOfSystemAsync_Trigger)(struct FlashManager *self);
    void (*ListAllVariableOfSystemAsync_Task)(struct FlashManager *self);
    void (*Async_Task)(struct FlashManager *self);
    uint8_t (*VariableIsExist)(struct FlashManager *self, char *name, uint16_t *index, uint32_t *bytes_sum_before_dat);
    uint8_t (*DataSolution)(struct FlashManager *self, DataUnit dat, uint32_t bytes_sum_before_dat, enum DataSolutionMethod data_solution, void *data);
    uint8_t (*CheckAllDataValid)(struct FlashManager *self);
    uint8_t (*EraseAll)(struct FlashManager *self);
    uint8_t (*SaveAllBase)(struct FlashManager *self);
    uint8_t (*EraseSectionOfVariable)(struct FlashManager *self, char *name);
    uint8_t (*SaveSectionOfVariable)(struct FlashManager *self, char *name);

    /* private method */

} FlashManager;

/* Variable Declare ***********************************************************/
extern DataConversion data_conversion;

/* Function Declare ***********************************************************/
void FlashManager_Init(struct FlashManager *self);
void FlashManager_RegisterVariableToTable(struct FlashManager *self, uint16_t data_num, uint8_t reboot_to_take_effect, void *data_addr, uint8_t data_len, char *data_type, char *name);
uint8_t FlashManager_SaveVariableIntoFlash(struct FlashManager *self, char *name);
uint8_t FlashManager_LoadVariableFromFlash(struct FlashManager *self, char *name);
uint8_t FlashManager_SaveAllVariableIntoFlash(struct FlashManager *self);
uint8_t FlashManager_LoadAllVariableFromFlash(struct FlashManager *self);
uint8_t FlashManager_ListVariableOfSystem(struct FlashManager *self, char *name);
uint8_t FlashManager_ListAllVariableOfSystem(struct FlashManager *self);
uint8_t FlashManager_WriteVariableIntoFlash(struct FlashManager *self, char *name, char *data_str);
uint8_t FlashManager_ReadVariableFromFlash(struct FlashManager *self, char *name);
uint8_t FlashManager_ReadAllVariableFromFlash(struct FlashManager *self);
void FlashManager_ReadAllVariableFromFlashAsync_Trigger(struct FlashManager *self);
void FlashManager_ReadAllVariableFromFlashAsync_Task(struct FlashManager *self);
void FlashManager_ListAllVariableOfSystemAsync_Trigger(struct FlashManager *self);
void FlashManager_ListAllVariableOfSystemAsync_Task(struct FlashManager *self);
void FlashManager_Async_Task(struct FlashManager *self);
uint8_t FlashManager_VariableIsExist(struct FlashManager *self, char *name, uint16_t *index, uint32_t *bytes_sum_before_dat);
uint8_t FlashManager_DataSolution(struct FlashManager *self, DataUnit dat, uint32_t bytes_sum_before_dat, enum DataSolutionMethod data_solution, void *data);
uint8_t FlashManager_CheckAllDataValid(struct FlashManager *self);
uint8_t FlashManager_EraseAll(struct FlashManager *self);
uint8_t FlashManager_SaveAllBase(struct FlashManager *self);
uint8_t FlashManager_EraseSectionOfVariable(struct FlashManager *self, char *name);
uint8_t FlashManager_SaveSectionOfVariable(struct FlashManager *self, char *name);

#endif